package com.wejoy.video.middle.station.admin.filter;

import com.wejoy.video.middle.station.admin.util.CurrentUserUtils;
import com.wejoy.video.middle.station.data.domain.system.SysLog;
import com.wejoy.video.middle.station.data.domain.system.SysUser;
import com.wejoy.video.middle.station.data.enums.dict.EnumSysLogType;
import com.wejoy.video.middle.station.data.service.system.ISysLogService;
import com.wejoy.video.middle.station.data.util.IPUtil;
import com.wejoy.video.middle.station.data.util.user.SysUserLoginUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 系统日志filter, 记录所有请求
 */
@Order(1002)
@Configuration
public class SysLogFilter implements HandlerInterceptor {
    private final static Logger logger = LoggerFactory.getLogger(SysLogFilter.class);
    @Autowired
    private ISysLogService sysLogService;
    /**
     * 50个线程, 无界队列, 超过异常
     */
    private final static ThreadPoolExecutor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(50, 50, 120, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), new ThreadPoolExecutor.AbortPolicy());

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        THREAD_POOL_EXECUTOR.submit(() -> {
            String userAgent = request.getHeader("User-Agent");
            SysLog sysLog = new SysLog();
            sysLog.setType(EnumSysLogType.LOG.getCode());
            // todo 尽量设置访问链接的菜单
            sysLog.setTitle(" ");
            sysLog.setRemoteAddr(IPUtil.getRemoteAddress(request));
            sysLog.setUserAgent(userAgent);
            sysLog.setRequestUri(buildUri(request));
            sysLog.setMethod(request.getMethod());
            if(!sysLog.getRequestUri().contains("/system/sysNotice/getPageList")){
                sysLog.setParams(getRequestBody(((BodyReaderHttpServletRequestWrapper) request).getBodyStr()));
                String sysUserToken = request.getHeader(SysUserLoginUtil.TOKEN);
                SysUser sysUser = SysUserLoginUtil.getLoginUser(sysUserToken);
                if (null != sysUser) {
                    sysLogService.save(sysLog, sysUser.getName());
                } else {
                    sysLogService.save(sysLog, "SYSTEM");
                }
            }
        });
        return true;
    }

    private Map<String, String> getAllHeader(HttpServletRequest request) {
        Enumeration<String> headerNames = request.getHeaderNames();
        Map<String, String> map = new HashMap<>();
        while (headerNames.hasMoreElements()) {
            String key = headerNames.nextElement();
            map.put(key, request.getHeader(key));
        }
        return map;
    }

    private String getRequestBody(String requestBody) {
        if (StringUtils.isEmpty(requestBody)) {
            return null;
        }
        return requestBody;
    }

    private String buildUri(HttpServletRequest request) {
        String path = request.getRequestURL().toString();
        String query = request.getQueryString();
        if (StringUtils.isEmpty(query)) {
            return path;
        }
        return path + "?" + query;
    }
}
